package com.mrd.spring.config;

import java.util.Properties;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;

import com.alibaba.druid.pool.xa.DruidXADataSource;
import com.atomikos.jdbc.AtomikosDataSourceBean;

@Configuration
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory",
    transactionManagerRef = "transactionManager", basePackages = {"com.mrd"})
public class JpaRepositoryConfig {

  @Autowired
  DataSourcePropertis dataSourcePropertis;
  @Value("${spring.datasource.url}")
  private String url;
  @Value("${spring.datasource.hongbao.url}")
  private String hongbaoUrl;
  @Value("${spring.datasource.qpdata.url}")
  private String qpdataUrl;
  @Value("${spring.datasource.hongbao.username}")
  private String hongbaoAccount;
  @Value("${spring.datasource.hongbao.password}")
  private String hongbaoPwd;
  @Value("${spring.datasource.qpdata.username}")
  private String qpdataAccount;
  @Value("${spring.datasource.qpdata.password}")
  private String qpdataPwd;

  @ConditionalOnClass(DataSourcePropertis.class)
  @Bean(name = "dataSource")
  @Primary
  public DataSource dataSource() {
    AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
    DruidXADataSource dataSource = new DruidXADataSource();
    dataSource.setUrl(dataSourcePropertis.getUrl());
    dataSource.setUsername(dataSourcePropertis.getUsername());
    dataSource.setPassword(dataSourcePropertis.getPassword());
    dataSource.setDriverClassName(dataSourcePropertis.getDriverClassName());
    dataSource.setInitialSize(dataSourcePropertis.getInitialSize());
    dataSource.setMinIdle(dataSourcePropertis.getMinIdle());
    dataSource.setMaxActive(dataSourcePropertis.getMaxActive());
    dataSource
        .setTimeBetweenEvictionRunsMillis(dataSourcePropertis.getMinEvictableIdleTimeMillis());
    dataSource.setMinEvictableIdleTimeMillis(dataSourcePropertis.getMinEvictableIdleTimeMillis());
    dataSource.setTestWhileIdle(true);// 在获取连接后，确定是否要进行连接空间时间的检查
    dataSource.setTestOnBorrow(true);// 获取连接检测
    dataSource.setTestOnReturn(false);// 获取连接检测
    dataSource.setValidationQuery("SELECT 'x' from dual");// 检测语句
    dataSource.setMaxPoolPreparedStatementPerConnectionSize(
        dataSourcePropertis.getMaxPoolPreparedStatementPerConnectionSize());
    ds.setUniqueResourceName("jpadataSource");
    ds.setPoolSize(dataSourcePropertis.getInitialSize());
    ds.setXaDataSource(dataSource);
    ds.setMaxPoolSize(dataSourcePropertis.getMaxActive());
    ds.setMaxIdleTime(dataSourcePropertis.getMaxWait());
    ds.setXaDataSourceClassName("oracle.jdbc.xa.client.OracleXADataSource");
    return ds;
  }

  @ConditionalOnClass(DataSource.class)
  @Bean(name = "entityManagerFactory")
  @Primary
  public LocalContainerEntityManagerFactoryBean entityManagerFactory(
      @Qualifier("dataSource") DataSource dataSource) {
    JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource(dataSource);
    em.setPackagesToScan(new String[] {"com.mrd"});
    em.setJpaVendorAdapter(vendorAdapter);
    Properties prop = new Properties();
    prop.setProperty("hibernate.connection.autocommit", "true");
    em.setJpaProperties(prop);
    em.setPersistenceUnitName("jpaEntityManager");
    return em;
  }

  @Bean(name = "jdbcTemplate")
  @Primary
  public JdbcTemplate jdbcTemplate(@Qualifier("dataSource") DataSource ds) {
    return new JdbcTemplate(ds);
  }

  @ConditionalOnClass(DataSourcePropertis.class)
  @Bean(name = "hongbaoDataSource")
  public DataSource hongbaoDataSource() {
    return getAtomikosDataSourceBean(hongbaoUrl, hongbaoAccount, hongbaoPwd,
        "hongbaoJpaDatasource");
  }

  @Bean(name = "hongbaoJdbcTemplate")
  public JdbcTemplate hongbaoJdbcTemplate(@Qualifier("hongbaoDataSource") DataSource ds) {
    return new JdbcTemplate(ds);
  }

  @ConditionalOnClass(DataSourcePropertis.class)
  @Bean(name = "qpDataSource")
  public DataSource qpDataSource() {
    return getAtomikosDataSourceBean(qpdataUrl, qpdataAccount, qpdataPwd, "qpdataJpaDatasource");
  }

  @Bean(name = "qpdataJdbcTemplate")
  public JdbcTemplate qpdataJdbcTemplate(@Qualifier("qpDataSource") DataSource ds) {
    return new JdbcTemplate(ds);
  }


  private AtomikosDataSourceBean getAtomikosDataSourceBean(String url, String username,
      String password, String uniqueName) {
    AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
    DruidXADataSource dataSource = new DruidXADataSource();
    dataSource.setUrl(url);
    dataSource.setUsername(username);
    dataSource.setPassword(password);
    dataSource.setDriverClassName(dataSourcePropertis.getDriverClassName());
    dataSource.setInitialSize(dataSourcePropertis.getInitialSize());
    dataSource.setMinIdle(dataSourcePropertis.getMinIdle());
    dataSource.setMaxActive(dataSourcePropertis.getMaxActive());
    dataSource
        .setTimeBetweenEvictionRunsMillis(dataSourcePropertis.getMinEvictableIdleTimeMillis());
    dataSource.setMinEvictableIdleTimeMillis(dataSourcePropertis.getMinEvictableIdleTimeMillis());
    dataSource.setTestWhileIdle(true);// 在获取连接后，确定是否要进行连接空间时间的检查
    dataSource.setTestOnBorrow(true);// 获取连接检测
    dataSource.setTestOnReturn(false);// 获取连接检测
    dataSource.setValidationQuery("SELECT 'x' from dual");// 检测语句
    ds.setUniqueResourceName(uniqueName);
    ds.setPoolSize(dataSourcePropertis.getInitialSize());
    ds.setXaDataSource(dataSource);
    ds.setMaxPoolSize(dataSourcePropertis.getMaxActive());
    ds.setMaxIdleTime(dataSourcePropertis.getMaxWait());
    ds.setXaDataSourceClassName("oracle.jdbc.xa.client.OracleXADataSource");
    return ds;
  }

}
